package com.syh.jn.scm.domain.supplier.entity.finance;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.repository.finance.StatementAccountBillReadRepository;
import com.syh.jn.scm.dto.supplier.finance.SalesInvoiceMto;
import com.syh.jn.scm.dto.supplier.finance.SalesInvoiceSto;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.finance.enums.SalesInvoiceEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;

/**
 * 销项发票
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SalesInvoice extends AbstractSimpleAggregate<Long> {
  public SalesInvoice() {
  }

  /**
   * 新增销项发票
   *
   * @param sto
   */
  public SalesInvoice(SalesInvoiceSto sto) {
    ExtAssert.notNull(sto, "对象为空");
    ValidationUtils.validate(sto);
    //系统默认生成的字段
    this.createTimeStamp = System.currentTimeMillis();
    //未签收状态
    this.state = SalesInvoiceEnum.NOT_SIGN.getStatus();
    //销项发票类型
    this.invoiceType = Short.valueOf("1");
    this.lockStatus = SalesInvoiceEnum.UN_LOCK.getStatus();
    ExtBeanUtils.copyProperties(sto, this, false);
    this.checkMoney();
  }

  /**
   * 修改销项发票
   *
   * @param mto
   */
  public void modify(SalesInvoiceMto mto) {
    ExtAssert.notNull(mto, "对象为空");
    ValidationUtils.validate(mto);
    if (SalesInvoiceEnum.SIGN_IN.getStatus().equals(this.state)) {
      throw new BusinessException("发票已确认签收,修改失败!");
    }
    this.lastUpdateTimeStamp = System.currentTimeMillis();
    ExtBeanUtils.copyProperties(mto, this, false);
    this.checkMoney();
  }

  /**
   * 数据销毁
   */
  public void destroy() {
    if (SalesInvoiceEnum.SIGN_IN.getStatus().equals(this.state)) {
      throw new BusinessException("发票已确认签收,删除失败!");
    }
  }

  /**
   * 确认签收
   */
  public void confirm() {
    this.checkMoney();
    this.signingTimestamp = System.currentTimeMillis();
    this.state = SalesInvoiceEnum.SIGN_IN.getStatus();
    this.lockStatus = SalesInvoiceEnum.LOCK.getStatus();
  }

  /**
   * 取消签收
   */
  public void cancel() {
    if (this.lockStatus.equals(SalesInvoiceEnum.LOCK.getStatus())) {
      throw new BusinessException("发票已经锁定,请联系管理员解锁,解锁后才能取消签收");
    }
    this.state = SalesInvoiceEnum.NOT_SIGN.getStatus();
    this.signingTimestamp = null;
  }

  /**
   * 解锁
   */
  public void unLock() {
    this.lockStatus = SalesInvoiceEnum.UN_LOCK.getStatus();
  }

  /**
   * 检查对账单金额
   */
  public void checkMoney() {
    if (this.price.compareTo(BigDecimal.ZERO) <= 0) {
      throw new BusinessException("开票金额不正确，请检查！");
    }
    StatementAccountBillReadRepository statementBillRead = (StatementAccountBillReadRepository) SpringContextUtils.getBean(StatementAccountBillReadRepository.class);
    StatementAccountBill statement = statementBillRead.getById(this.statementOfAccountId);

    if (this.id == null) {
      BigDecimal notGeneratedTicketAmt = statement.getPrice().subtract(statement.getGeneratedTicketPrice());
      if (this.price.compareTo(notGeneratedTicketAmt) > 0) {
        throw new BusinessException("当前对账单未生成开票金额为：" + notGeneratedTicketAmt + "元。开票金额不能大于未生成金额！");
      }
    }

    BigDecimal notPaymentAmt = statement.getPrice().subtract(statement.getTicketPrice());
    if (this.price.compareTo(notPaymentAmt) > 0) {
      throw new BusinessException("当前对账单未开票金额为：" + notPaymentAmt + "元。付款金额不能大于未开票金额！");
    }
  }

  /**
   * 对账单id
   */
  private Long statementOfAccountId;
  /**
   * 录单人id
   */
  private Long brokerageId;
  /**
   * 开票总额
   */
  private BigDecimal price;
  /**
   * 发票数量
   */
  private Long invoiceCount;
  /**
   * 快递单编号
   */
  private String expressListCode;
  /**
   * 快递公司
   */
  private String expressCompany;
  /**
   * 开票日期
   */
  private Long billingTimestamp;
  /**
   * 收票日期
   */
  private Long signingTimestamp;
  /**
   * 我方发票基本信息:公司名称
   */
  private String ourInvoiceCompanyName;
  /**
   * 我方发票基本信息:收款银行名称
   */
  private String ourInvoiceBankName;
  /**
   * 我方发票基本信息:收款银行账户
   */
  private String ourInvoiceBankAccount;
  /**
   * 我方发票基本信息:纳税人识别号
   */
  private String ourInvoiceTaxpayerCode;
  /**
   * 对方发票基本信息:公司名称
   */
  private String otherPartyInvoiceCompanyName;
  /**
   * 对方发票基本信息:收款银行名称
   */
  private String otherPartyInvoiceBankName;
  /**
   * 对方发票基本信息:收款银行账户
   */
  private String otherPartyInvoiceBankAccount;
  /**
   * 对方发票基本信息:纳税人识别号
   */
  private String otherPartyInvoiceTaxpayerCode;
  /**
   * 开票状态: 0未签收, 1已签收
   */
  private Short state;
  /**
   * 发票类型:-1进项发票,1销项发票
   */
  private Short invoiceType;
  /**
   * 签收商家
   */
  private Long signForCompanyId;
  /**
   * 归属端id
   */
  private Long businessEntityId;
  /**
   * 锁定状态(0 未锁定 1 已锁定 )签收后就锁定它，锁定后为最终状态，将不可再修改
   */
  private Short lockStatus;
}
